package com.zhike.service.file;

import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;

import javax.annotation.Resource;

import org.liuxp.minioplus.api.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.eva.epc.common.file.FileHelper;
import com.eva.epc.common.util.se.ImgEqualScaleAndCutHelper;
import com.zhike.common.conf.IMBaseConf;
import com.zhike.common.constant.Constants;
import com.zhike.common.constant.SysConfigConstants;
import com.zhike.common.enums.YesNoEnum;
import com.zhike.common.utils.AliSecurityCheckUtils;
import com.zhike.mapper.user.UsersMapper;
import com.zhike.service.store.Alioss;
import com.zhike.service.system.ISystemConfigService;
import com.zhike.utils.cache.UsersInfoCacheProvider;

import lombok.extern.slf4j.Slf4j;

/**
 * 用户头像上传实现类.
 * 
 * @version 1.0
 * @revision 1.1, 20170306 by Jack Jiang: 已规范化跨平台文件上传时额外参数的接收
 */
@Slf4j
@Component
public class UserAvatarUploader extends UploaderRoot {
  @Resource
  private UsersMapper usersMapper;
  @Resource
  private IMBaseConf baseConf;

  @Autowired
  private StorageService storageService;

  @Autowired
  private UsersInfoCacheProvider usersInfoCacheProvider;

  @Autowired
  private ISystemConfigService systemConfigService;

  @Autowired
  private Alioss alioss;

  @Override
  public String getFileSaveDir() {
    return baseConf.getDIR_USER_AVATAR_UPLOAD();
  }

  @Override
  public void onUploadSucess(HashMap<String, Object> parametersFromClient) throws Exception {
    String url = (String) parametersFromClient.get("url");
    String userUid = (String) parametersFromClient.get("user_uid");
    String fileName = (String) parametersFromClient.get("file_name");

    log.debug("[" + getDebugTAG() + "] 用户" + userUid + "的头像文件" + fileName + "数据上传成功，马上处理其它业务逻辑...");

    // 客户端传过来的数据（参数）的合法性检查
    if (StringUtils.isNotBlank(userUid) && StringUtils.isNotBlank(fileName) && StringUtils.isNotBlank(url)) {
      Integer conf = systemConfigService.getValueByKeyAsInt(SysConfigConstants.CONFIG_TYPE_SECURITY,
          SysConfigConstants.CONFIG_USER_PROFILE);
      if (conf != null && conf.equals(YesNoEnum.YES.getValue())) {

        // 校验头像图片是否合规
        if (!AliSecurityCheckUtils.imageScan(url, "profilePhotoCheck")) {
          log.warn("FileKey: {} 不合规", fileName);
          String storage = systemConfigService.getValueByKey("storage", "default");
          if (storage.equals("minio")) {
            // 删除
            storageService.remove(fileName);
          } else if (storage.equals("aliyun")) {
            alioss.deleteFile(fileName);
          }

          log.warn("uid: {} 头像图片: {}不合规 已删除", userUid, fileName);
          return;
        }
      }

      // 用户新头像数据成功保存成文件之后要做的事：删除老头像文
      // 件并把最新的文件名更新到用户数据表中
      usersMapper.updateUserAvatar(userUid, fileName);
      usersInfoCacheProvider.reloadOneCache(userUid);
    } else {
      throw new Exception("[" + getDebugTAG() + "] 缺少参数 ");
    }
  }

  @Override
  public void onUploadFailure(Exception ex) {
    log.error("[" + getDebugTAG() + "] 处理用户头像上传时出错了，" + ex.getMessage(), ex);
  }

  @Override
  public String getDebugTAG() {
    return "HTTP头像上传";
  }

  /**
   * 用户新头像数据成功保存成文件之后要做的事：删除老头像文件并把最新的文件名更新到用户数据表中等.
   * 
   * @param userUid
   * @param fileName
   * @throws Exception
   */
  public void afterSavedAvatarFile(String userUid, String fileName) throws Exception {
    try {
      // 尝试生成新头像的缩略图(@since 4.3)
      // @since 4.3：当前生成的缩略图仅用于在群聊头像拼合时提升服务端性能等，暂无它用！
      try {
        String newFilePath = baseConf.getDIR_USER_AVATAR_UPLOAD() + fileName;
        String newFileThumbPath = baseConf.getDIR_USER_AVATAR_UPLOAD()
            + "th_" + fileName;

        // 20170306后的缩略图生成算法
        ImgEqualScaleAndCutHelper.saveImageAsJpg(newFilePath, newFileThumbPath, 120, 120);
      } catch (Exception e) {
        log.warn(e.getMessage(), e);
      }

      // 尝试去删除用户之前的老头像（新头像已上传，则老头像就没有意义了）
      String oldUserAvatarFileName = usersMapper.selectUserAvatar(userUid);
      if (oldUserAvatarFileName != null) {
        // 旧头像文件路径
        String oldFilePath = baseConf.getDIR_USER_AVATAR_UPLOAD() + oldUserAvatarFileName;
        // 删除旧头像图片文件
        FileHelper.deleteFile(oldFilePath);

        // 旧头像缩略图文件路径
        String oldThumbFilePath = baseConf.getDIR_USER_AVATAR_UPLOAD()
            + "th_" + oldUserAvatarFileName;
        // 删除旧头像缩略图片文件(@since 4.3)
        FileHelper.deleteFile(oldThumbFilePath);

        log.debug("[HTTP头像上传] 成功删除了用户的老头像：" + oldFilePath);
      }

      // 更新数据库，将该用户的头像文件名update到数据库哦
      Integer c = usersMapper.updateUserAvatar(userUid, fileName);
      log.debug("更新用户头像 {} 行", c);
    } catch (Exception e) {
      throw e;
    }
  }

  @Override
  public String getPathTag() {
    return Constants.UPLOAD_AVATAR;
  }

  @Override
  public Set<String> getDetectedTypes() {
    Set<String> allowExtensions = new HashSet<>();
    allowExtensions.add("image/png");
    allowExtensions.add("image/jpeg");
    allowExtensions.add("image/jpg");
    allowExtensions.add("image/gif");
    return allowExtensions;
  }
}
